package com.ysy.tz.core.skin;

import com.sun.javafx.css.converters.BooleanConverter;
import com.sun.javafx.css.converters.EnumConverter;
import com.sun.javafx.css.converters.SizeConverter;
import com.sun.javafx.scene.control.behavior.PaginationBehavior;
import com.sun.javafx.scene.control.skin.BehaviorSkinBase;
import com.sun.javafx.scene.control.skin.Utils;
import com.sun.javafx.scene.control.skin.resources.ControlResources;
import com.ysy.tz.core.selfcomp.CustomerPagination;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javafx.animation.Interpolator;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.css.CssMetaData;
import javafx.css.Styleable;
import javafx.css.StyleableBooleanProperty;
import javafx.css.StyleableDoubleProperty;
import javafx.css.StyleableObjectProperty;
import javafx.css.StyleableProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Side;
import javafx.geometry.VPos;
import javafx.scene.AccessibleAction;
import javafx.scene.AccessibleAttribute;
import javafx.scene.AccessibleRole;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Control;
import javafx.scene.control.Label;
import javafx.scene.control.Pagination;
import javafx.scene.control.SkinBase;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.control.Tooltip;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.TouchEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;

public class CustomerPaginationSkin extends BehaviorSkinBase<Pagination, PaginationBehavior> {
    private static final Duration DURATION = new Duration(125.0);
    private static final double SWIPE_THRESHOLD = 0.3;
    private static final double TOUCH_THRESHOLD = 15.0;
    private StackPane currentStackPane;
    private StackPane nextStackPane;
    private Timeline timeline;
    private Rectangle clipRect = new Rectangle();
    private NavigationControl navigation;
    private int fromIndex;
    private int previousIndex;
    private int currentIndex;
    private int toIndex;
    private int pageCount;
    private int maxPageIndicatorCount;
    private boolean animate = true;
    private HBox controlBox;
    private Button prev;
    private Button next;
    private Button first;
    private Button last;
    private CustomerPagination pagination;
    private Label totalLabel;
    private Label suffixLabel = new Label(" 条记录 ");
    private ComboBox pageSizeComboBox;
    ObservableList pageSize = FXCollections.observableArrayList(new Integer[]{20, 50, 100, 200, 500});
    private double startTouchPos;
    private double lastTouchPos;
    private long startTouchTime;
    private long lastTouchTime;
    private double touchVelocity;
    private boolean touchThresholdBroken;
    private int touchEventId = -1;
    private boolean nextPageReached = false;
    private boolean setInitialDirection = false;
    private int direction;
    private static final Interpolator interpolator = Interpolator.SPLINE(0.4829, 0.5709, 0.6803, 0.9928);
    private int currentAnimatedIndex;
    private boolean hasPendingAnimation = false;
    private EventHandler<ActionEvent> swipeAnimationEndEventHandler = new EventHandler<ActionEvent>() {
        public void handle(ActionEvent t) {
            CustomerPaginationSkin.this.swapPanes();
            CustomerPaginationSkin.this.timeline = null;
            if (CustomerPaginationSkin.this.hasPendingAnimation) {
                CustomerPaginationSkin.this.animateSwitchPage();
                CustomerPaginationSkin.this.hasPendingAnimation = false;
            }

        }
    };
    private EventHandler<ActionEvent> clampAnimationEndEventHandler = new EventHandler<ActionEvent>() {
        public void handle(ActionEvent t) {
            CustomerPaginationSkin.this.currentStackPane.setTranslateX(0.0);
            CustomerPaginationSkin.this.nextStackPane.setTranslateX(0.0);
            CustomerPaginationSkin.this.nextStackPane.setVisible(false);
            CustomerPaginationSkin.this.timeline = null;
        }
    };
    private final DoubleProperty arrowButtonGap = new StyleableDoubleProperty(60.0) {
        public Object getBean() {
            return CustomerPaginationSkin.this;
        }

        public String getName() {
            return "arrowButtonGap";
        }

        public CssMetaData<Pagination, Number> getCssMetaData() {
            return CustomerPaginationSkin.StyleableProperties.ARROW_BUTTON_GAP;
        }
    };
    private BooleanProperty arrowsVisible;
    private BooleanProperty pageInformationVisible;
    private ObjectProperty<Side> pageInformationAlignment;
    private BooleanProperty tooltipVisible;
    private static final Boolean DEFAULT_ARROW_VISIBLE;
    private static final Boolean DEFAULT_PAGE_INFORMATION_VISIBLE;
    private static final Side DEFAULT_PAGE_INFORMATION_ALIGNMENT;
    private static final Boolean DEFAULT_TOOLTIP_VISIBLE;

    private void patchNavigation() {
        Node control = this.pagination.lookup(".control-box");
        if (control instanceof HBox) {
            this.controlBox = (HBox)control;
            this.controlBox.setSpacing(0.0);
            this.prev = (Button)this.controlBox.getChildren().get(0);
            this.next = (Button)this.controlBox.getChildren().get(this.controlBox.getChildren().size() - 1);
            this.first = new Button("<<");
            this.first.setOnAction((e) -> {
                this.pagination.setCurrentPageIndex(0);
            });
            this.first.disableProperty().bind(this.pagination.currentPageIndexProperty().isEqualTo(0));
            this.last = new Button(">>");
            this.last.setOnAction((e) -> {
                this.pagination.setCurrentPageIndex(this.pagination.getPageCount() - 1);
            });
            this.last.disableProperty().bind(this.pagination.currentPageIndexProperty().isEqualTo(this.pagination.getPageCount() - 1));
            System.out.println("----------->>> customerPaginationSkin render!");
            this.pageSizeComboBox = new ComboBox();
            this.pageSizeComboBox.setItems(this.pageSize);
            this.pageSizeComboBox.getSelectionModel().selectFirst();
            this.pageSizeComboBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
                public void changed(ObservableValue observable, Object oldValue, Object newValue) {
                    CustomerPaginationSkin.this.pagination.setPageSize((Integer)newValue);
                }
            });
            this.totalLabel = new Label();
            this.refresh();
            this.totalLabel.setPadding(new Insets(10.0));
            this.suffixLabel.setPadding(new Insets(10.0));
            ListChangeListener childrenListener = (c) -> {
                while(c.next()) {
                    if (c.wasAdded() && !c.wasRemoved() && c.getAddedSize() == 1 && c.getAddedSubList().get(0) == this.next) {
                        this.addCustomNodes();
                    }
                }

            };
            this.controlBox.getChildren().addListener(childrenListener);
            this.addCustomNodes();
        }
    }

    public void refresh() {
        this.totalLabel.setText("显示第 " + this.pagination.getCurrentStartRow() + " 到第 " + this.pagination.getCurrentEndRow() + " 条记录，总共 " + this.pagination.getTotalRow() + " 条记录每页显示");
        this.last.disableProperty().unbind();
        this.last.disableProperty().bind(this.pagination.currentPageIndexProperty().isEqualTo(this.pagination.getPageCount() - 1));
    }

    protected void addCustomNodes() {
        if (this.first.getParent() != this.controlBox) {
            this.controlBox.getChildren().add(0, this.first);
            this.controlBox.getChildren().add(0, this.suffixLabel);
            this.controlBox.getChildren().add(0, this.pageSizeComboBox);
            this.controlBox.getChildren().add(0, this.totalLabel);
            this.controlBox.getChildren().add(this.last);
        }
    }

    public CustomerPaginationSkin(CustomerPagination pagination) {
        super(pagination, new PaginationBehavior(pagination));
        ((Pagination)this.getSkinnable()).setClip(this.clipRect);
        this.pagination = pagination;
        this.currentStackPane = new StackPane();
        this.currentStackPane.getStyleClass().add("page");
        this.nextStackPane = new StackPane();
        this.nextStackPane.getStyleClass().add("page");
        this.nextStackPane.setVisible(false);
        this.navigation = new NavigationControl();
        this.getChildren().addAll(new Node[]{this.currentStackPane, this.nextStackPane, this.navigation});
        pagination.maxPageIndicatorCountProperty().addListener((o) -> {
            this.resetIndiciesAndNav();
        });
        this.registerChangeListener(pagination.widthProperty(), "WIDTH");
        this.registerChangeListener(pagination.heightProperty(), "HEIGHT");
        this.registerChangeListener(pagination.pageCountProperty(), "PAGE_COUNT");
        this.registerChangeListener(pagination.pageFactoryProperty(), "PAGE_FACTORY");
        this.initializeSwipeAndTouchHandlers();
        this.pagination = pagination;
        this.patchNavigation();
    }

    protected void resetIndiciesAndNav() {
        this.resetIndexes(false);
        this.navigation.initializePageIndicators();
        this.navigation.updatePageIndicators();
    }

    public void selectNext() {
        if (this.getCurrentPageIndex() < this.getPageCount() - 1) {
            this.pagination.setCurrentPageIndex(this.getCurrentPageIndex() + 1);
        }

    }

    public void selectPrevious() {
        if (this.getCurrentPageIndex() > 0) {
            this.pagination.setCurrentPageIndex(this.getCurrentPageIndex() - 1);
        }

    }

    private void initializeSwipeAndTouchHandlers() {
        Pagination control = (Pagination)this.getSkinnable();
        ((Pagination)this.getSkinnable()).addEventHandler(TouchEvent.TOUCH_PRESSED, (e) -> {
            if (this.touchEventId == -1) {
                this.touchEventId = e.getTouchPoint().getId();
            }

            if (this.touchEventId == e.getTouchPoint().getId()) {
                this.lastTouchPos = this.startTouchPos = e.getTouchPoint().getX();
                this.lastTouchTime = this.startTouchTime = System.currentTimeMillis();
                this.touchThresholdBroken = false;
                e.consume();
            }
        });
        ((Pagination)this.getSkinnable()).addEventHandler(TouchEvent.TOUCH_MOVED, (e) -> {
            if (this.touchEventId == e.getTouchPoint().getId()) {
                double drag = e.getTouchPoint().getX() - this.lastTouchPos;
                long time = System.currentTimeMillis() - this.lastTouchTime;
                this.touchVelocity = drag / (double)time;
                this.lastTouchPos = e.getTouchPoint().getX();
                this.lastTouchTime = System.currentTimeMillis();
                double delta = e.getTouchPoint().getX() - this.startTouchPos;
                if (!this.touchThresholdBroken && Math.abs(delta) > 15.0) {
                    this.touchThresholdBroken = true;
                }

                if (this.touchThresholdBroken) {
                    double width = control.getWidth() - (this.snappedLeftInset() + this.snappedRightInset());
                    if (!this.setInitialDirection) {
                        this.setInitialDirection = true;
                        this.direction = delta < 0.0 ? 1 : -1;
                    }

                    double currentPaneX;
                    double nextPaneX;
                    if (delta < 0.0) {
                        if (this.direction == -1) {
                            this.nextStackPane.getChildren().clear();
                            this.direction = 1;
                        }

                        if (Math.abs(delta) <= width) {
                            currentPaneX = delta;
                            nextPaneX = width + delta;
                            this.nextPageReached = false;
                        } else {
                            currentPaneX = -width;
                            nextPaneX = 0.0;
                            this.nextPageReached = true;
                        }

                        this.currentStackPane.setTranslateX(currentPaneX);
                        if (this.getCurrentPageIndex() < this.getPageCount() - 1) {
                            this.createPage(this.nextStackPane, this.currentIndex + 1);
                            this.nextStackPane.setVisible(true);
                            this.nextStackPane.setTranslateX(nextPaneX);
                        } else {
                            this.currentStackPane.setTranslateX(0.0);
                        }
                    } else {
                        if (this.direction == 1) {
                            this.nextStackPane.getChildren().clear();
                            this.direction = -1;
                        }

                        if (Math.abs(delta) <= width) {
                            currentPaneX = delta;
                            nextPaneX = -width + delta;
                            this.nextPageReached = false;
                        } else {
                            currentPaneX = width;
                            nextPaneX = 0.0;
                            this.nextPageReached = true;
                        }

                        this.currentStackPane.setTranslateX(currentPaneX);
                        if (this.getCurrentPageIndex() != 0) {
                            this.createPage(this.nextStackPane, this.currentIndex - 1);
                            this.nextStackPane.setVisible(true);
                            this.nextStackPane.setTranslateX(nextPaneX);
                        } else {
                            this.currentStackPane.setTranslateX(0.0);
                        }
                    }
                }

                e.consume();
            }
        });
        ((Pagination)this.getSkinnable()).addEventHandler(TouchEvent.TOUCH_RELEASED, (e) -> {
            if (this.touchEventId == e.getTouchPoint().getId()) {
                this.touchEventId = -1;
                this.setInitialDirection = false;
                if (this.touchThresholdBroken) {
                    double drag = e.getTouchPoint().getX() - this.startTouchPos;
                    long time = System.currentTimeMillis() - this.startTouchTime;
                    boolean quick = time < 300L;
                    double velocity = quick ? drag / (double)time : this.touchVelocity;
                    double distance = velocity * 500.0;
                    double width = control.getWidth() - (this.snappedLeftInset() + this.snappedRightInset());
                    double threshold = Math.abs(distance / width);
                    double delta = Math.abs(drag / width);
                    if (!(threshold > 0.3) && !(delta > 0.3)) {
                        this.animateClamping(this.startTouchPos > e.getTouchPoint().getSceneX());
                    } else if (this.startTouchPos > e.getTouchPoint().getX()) {
                        this.selectNext();
                    } else {
                        this.selectPrevious();
                    }
                }

                e.consume();
            }
        });
    }

    private void resetIndexes(boolean usePageIndex) {
        this.maxPageIndicatorCount = this.getMaxPageIndicatorCount();
        this.pageCount = this.getPageCount();
        if (this.pageCount > this.maxPageIndicatorCount) {
            this.pageCount = this.maxPageIndicatorCount;
        }

        this.fromIndex = 0;
        this.previousIndex = 0;
        this.currentIndex = usePageIndex ? this.getCurrentPageIndex() : 0;
        this.toIndex = this.pageCount - 1;
        if (this.pageCount == Integer.MAX_VALUE && this.maxPageIndicatorCount == Integer.MAX_VALUE) {
            this.toIndex = 0;
        }

        boolean isAnimate = this.animate;
        if (isAnimate) {
            this.animate = false;
        }

        this.currentStackPane.getChildren().clear();
        this.nextStackPane.getChildren().clear();
        this.pagination.setCurrentPageIndex(this.currentIndex);
        this.createPage(this.currentStackPane, this.currentIndex);
        if (isAnimate) {
            this.animate = true;
        }

    }

    private boolean createPage(StackPane pane, int index) {
        if (this.pagination.getPageFactory() != null && pane.getChildren().isEmpty()) {
            Node content = (Node)this.pagination.getPageFactory().call(index);
            if (content != null) {
                pane.getChildren().setAll(new Node[]{content});
                return true;
            } else {
                boolean isAnimate = this.animate;
                if (isAnimate) {
                    this.animate = false;
                }

                if (this.pagination.getPageFactory().call(this.previousIndex) != null) {
                    this.pagination.setCurrentPageIndex(this.previousIndex);
                } else {
                    this.pagination.setCurrentPageIndex(0);
                }

                if (isAnimate) {
                    this.animate = true;
                }

                return false;
            }
        } else {
            return false;
        }
    }

    private int getPageCount() {
        return ((Pagination)this.getSkinnable()).getPageCount() < 1 ? 1 : ((Pagination)this.getSkinnable()).getPageCount();
    }

    private int getMaxPageIndicatorCount() {
        return ((Pagination)this.getSkinnable()).getMaxPageIndicatorCount();
    }

    private int getCurrentPageIndex() {
        return ((Pagination)this.getSkinnable()).getCurrentPageIndex();
    }

    private void animateSwitchPage() {
        if (this.timeline != null) {
            this.timeline.setRate(8.0);
            this.hasPendingAnimation = true;
        } else if (this.nextStackPane.isVisible() || this.createPage(this.nextStackPane, this.currentAnimatedIndex)) {
            if (this.nextPageReached) {
                this.swapPanes();
                this.nextPageReached = false;
            } else {
                this.nextStackPane.setCache(true);
                this.currentStackPane.setCache(true);
                Platform.runLater(() -> {
                    boolean useTranslateX = this.nextStackPane.getTranslateX() != 0.0;
                    KeyFrame k1;
                    KeyFrame k2;
                    if (this.currentAnimatedIndex > this.previousIndex) {
                        if (!useTranslateX) {
                            this.nextStackPane.setTranslateX(this.currentStackPane.getWidth());
                        }

                        this.nextStackPane.setVisible(true);
                        this.timeline = new Timeline();
                        k1 = new KeyFrame(Duration.millis(0.0), new KeyValue[]{new KeyValue(this.currentStackPane.translateXProperty(), useTranslateX ? this.currentStackPane.getTranslateX() : 0.0, interpolator), new KeyValue(this.nextStackPane.translateXProperty(), useTranslateX ? this.nextStackPane.getTranslateX() : this.currentStackPane.getWidth(), interpolator)});
                        k2 = new KeyFrame(DURATION, this.swipeAnimationEndEventHandler, new KeyValue[]{new KeyValue(this.currentStackPane.translateXProperty(), -this.currentStackPane.getWidth(), interpolator), new KeyValue(this.nextStackPane.translateXProperty(), 0, interpolator)});
                        this.timeline.getKeyFrames().setAll(new KeyFrame[]{k1, k2});
                        this.timeline.play();
                    } else {
                        if (!useTranslateX) {
                            this.nextStackPane.setTranslateX(-this.currentStackPane.getWidth());
                        }

                        this.nextStackPane.setVisible(true);
                        this.timeline = new Timeline();
                        k1 = new KeyFrame(Duration.millis(0.0), new KeyValue[]{new KeyValue(this.currentStackPane.translateXProperty(), useTranslateX ? this.currentStackPane.getTranslateX() : 0.0, interpolator), new KeyValue(this.nextStackPane.translateXProperty(), useTranslateX ? this.nextStackPane.getTranslateX() : -this.currentStackPane.getWidth(), interpolator)});
                        k2 = new KeyFrame(DURATION, this.swipeAnimationEndEventHandler, new KeyValue[]{new KeyValue(this.currentStackPane.translateXProperty(), this.currentStackPane.getWidth(), interpolator), new KeyValue(this.nextStackPane.translateXProperty(), 0, interpolator)});
                        this.timeline.getKeyFrames().setAll(new KeyFrame[]{k1, k2});
                        this.timeline.play();
                    }

                });
            }
        }
    }

    private void swapPanes() {
        StackPane temp = this.currentStackPane;
        this.currentStackPane = this.nextStackPane;
        this.nextStackPane = temp;
        this.currentStackPane.setTranslateX(0.0);
        this.currentStackPane.setCache(false);
        this.nextStackPane.setTranslateX(0.0);
        this.nextStackPane.setCache(false);
        this.nextStackPane.setVisible(false);
        this.nextStackPane.getChildren().clear();
    }

    private void animateClamping(boolean rightToLeft) {
        KeyFrame k1;
        KeyFrame k2;
        if (rightToLeft) {
            this.timeline = new Timeline();
            k1 = new KeyFrame(Duration.millis(0.0), new KeyValue[]{new KeyValue(this.currentStackPane.translateXProperty(), this.currentStackPane.getTranslateX(), interpolator), new KeyValue(this.nextStackPane.translateXProperty(), this.nextStackPane.getTranslateX(), interpolator)});
            k2 = new KeyFrame(DURATION, this.clampAnimationEndEventHandler, new KeyValue[]{new KeyValue(this.currentStackPane.translateXProperty(), 0, interpolator), new KeyValue(this.nextStackPane.translateXProperty(), this.currentStackPane.getWidth(), interpolator)});
            this.timeline.getKeyFrames().setAll(new KeyFrame[]{k1, k2});
            this.timeline.play();
        } else {
            this.timeline = new Timeline();
            k1 = new KeyFrame(Duration.millis(0.0), new KeyValue[]{new KeyValue(this.currentStackPane.translateXProperty(), this.currentStackPane.getTranslateX(), interpolator), new KeyValue(this.nextStackPane.translateXProperty(), this.nextStackPane.getTranslateX(), interpolator)});
            k2 = new KeyFrame(DURATION, this.clampAnimationEndEventHandler, new KeyValue[]{new KeyValue(this.currentStackPane.translateXProperty(), 0, interpolator), new KeyValue(this.nextStackPane.translateXProperty(), -this.currentStackPane.getWidth(), interpolator)});
            this.timeline.getKeyFrames().setAll(new KeyFrame[]{k1, k2});
            this.timeline.play();
        }

    }

    private DoubleProperty arrowButtonGapProperty() {
        return this.arrowButtonGap;
    }

    public final void setArrowsVisible(boolean value) {
        this.arrowsVisibleProperty().set(value);
    }

    public final boolean isArrowsVisible() {
        return this.arrowsVisible == null ? DEFAULT_ARROW_VISIBLE : this.arrowsVisible.get();
    }

    public final BooleanProperty arrowsVisibleProperty() {
        if (this.arrowsVisible == null) {
            this.arrowsVisible = new StyleableBooleanProperty(DEFAULT_ARROW_VISIBLE) {
                protected void invalidated() {
                    ((Pagination)CustomerPaginationSkin.this.getSkinnable()).requestLayout();
                }

                public CssMetaData<Pagination, Boolean> getCssMetaData() {
                    return CustomerPaginationSkin.StyleableProperties.ARROWS_VISIBLE;
                }

                public Object getBean() {
                    return CustomerPaginationSkin.this;
                }

                public String getName() {
                    return "arrowVisible";
                }
            };
        }

        return this.arrowsVisible;
    }

    public final void setPageInformationVisible(boolean value) {
        this.pageInformationVisibleProperty().set(value);
    }

    public final boolean isPageInformationVisible() {
        return this.pageInformationVisible == null ? DEFAULT_PAGE_INFORMATION_VISIBLE : this.pageInformationVisible.get();
    }

    public final BooleanProperty pageInformationVisibleProperty() {
        if (this.pageInformationVisible == null) {
            this.pageInformationVisible = new StyleableBooleanProperty(DEFAULT_PAGE_INFORMATION_VISIBLE) {
                protected void invalidated() {
                    ((Pagination)CustomerPaginationSkin.this.getSkinnable()).requestLayout();
                }

                public CssMetaData<Pagination, Boolean> getCssMetaData() {
                    return CustomerPaginationSkin.StyleableProperties.PAGE_INFORMATION_VISIBLE;
                }

                public Object getBean() {
                    return CustomerPaginationSkin.this;
                }

                public String getName() {
                    return "pageInformationVisible";
                }
            };
        }

        return this.pageInformationVisible;
    }

    public final void setPageInformationAlignment(Side value) {
        this.pageInformationAlignmentProperty().set(value);
    }

    public final Side getPageInformationAlignment() {
        return this.pageInformationAlignment == null ? DEFAULT_PAGE_INFORMATION_ALIGNMENT : (Side)this.pageInformationAlignment.get();
    }

    public final ObjectProperty<Side> pageInformationAlignmentProperty() {
        if (this.pageInformationAlignment == null) {
            this.pageInformationAlignment = new StyleableObjectProperty<Side>(Side.BOTTOM) {
                protected void invalidated() {
                    ((Pagination)CustomerPaginationSkin.this.getSkinnable()).requestLayout();
                }

                public CssMetaData<Pagination, Side> getCssMetaData() {
                    return CustomerPaginationSkin.StyleableProperties.PAGE_INFORMATION_ALIGNMENT;
                }

                public Object getBean() {
                    return CustomerPaginationSkin.this;
                }

                public String getName() {
                    return "pageInformationAlignment";
                }
            };
        }

        return this.pageInformationAlignment;
    }

    public final void setTooltipVisible(boolean value) {
        this.tooltipVisibleProperty().set(value);
    }

    public final boolean isTooltipVisible() {
        return this.tooltipVisible == null ? DEFAULT_TOOLTIP_VISIBLE : this.tooltipVisible.get();
    }

    public final BooleanProperty tooltipVisibleProperty() {
        if (this.tooltipVisible == null) {
            this.tooltipVisible = new StyleableBooleanProperty(DEFAULT_TOOLTIP_VISIBLE) {
                protected void invalidated() {
                    ((Pagination)CustomerPaginationSkin.this.getSkinnable()).requestLayout();
                }

                public CssMetaData<Pagination, Boolean> getCssMetaData() {
                    return CustomerPaginationSkin.StyleableProperties.TOOLTIP_VISIBLE;
                }

                public Object getBean() {
                    return CustomerPaginationSkin.this;
                }

                public String getName() {
                    return "tooltipVisible";
                }
            };
        }

        return this.tooltipVisible;
    }

    protected void handleControlPropertyChanged(String p) {
        super.handleControlPropertyChanged(p);
        if ("PAGE_FACTORY".equals(p)) {
            if (this.animate && this.timeline != null) {
                this.timeline.setRate(8.0);
                this.timeline.setOnFinished((arg0) -> {
                    this.resetIndiciesAndNav();
                });
                return;
            }

            this.resetIndiciesAndNav();
        } else if ("PAGE_COUNT".equals(p)) {
            this.resetIndiciesAndNav();
        } else if ("WIDTH".equals(p)) {
            this.clipRect.setWidth(((Pagination)this.getSkinnable()).getWidth());
        } else if ("HEIGHT".equals(p)) {
            this.clipRect.setHeight(((Pagination)this.getSkinnable()).getHeight());
        }

        ((Pagination)this.getSkinnable()).requestLayout();
    }

    protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
        double navigationWidth = this.navigation.isVisible() ? this.snapSize(this.navigation.minWidth(height)) : 0.0;
        return leftInset + Math.max(this.currentStackPane.minWidth(height), navigationWidth) + rightInset;
    }

    protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
        double navigationHeight = this.navigation.isVisible() ? this.snapSize(this.navigation.minHeight(width)) : 0.0;
        return topInset + this.currentStackPane.minHeight(width) + navigationHeight + bottomInset;
    }

    protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
        double navigationWidth = this.navigation.isVisible() ? this.snapSize(this.navigation.prefWidth(height)) : 0.0;
        return leftInset + Math.max(this.currentStackPane.prefWidth(height), navigationWidth) + rightInset;
    }

    protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
        double navigationHeight = this.navigation.isVisible() ? this.snapSize(this.navigation.prefHeight(width)) : 0.0;
        return topInset + this.currentStackPane.prefHeight(width) + navigationHeight + bottomInset;
    }

    protected void layoutChildren(double x, double y, double w, double h) {
        double navigationHeight = this.navigation.isVisible() ? this.snapSize(this.navigation.prefHeight(-1.0)) : 0.0;
        double stackPaneHeight = this.snapSize(h - navigationHeight);
        this.layoutInArea(this.currentStackPane, x, y, w, stackPaneHeight, 0.0, HPos.CENTER, VPos.CENTER);
        this.layoutInArea(this.nextStackPane, x, y, w, stackPaneHeight, 0.0, HPos.CENTER, VPos.CENTER);
        this.layoutInArea(this.navigation, x, stackPaneHeight, w, navigationHeight, 0.0, HPos.CENTER, VPos.CENTER);
    }

    protected Object queryAccessibleAttribute(AccessibleAttribute attribute, Object... parameters) {
        switch (attribute) {
            case FOCUS_ITEM:
                return this.navigation.indicatorButtons.getSelectedToggle();
            case ITEM_COUNT:
                return this.navigation.indicatorButtons.getToggles().size();
            case ITEM_AT_INDEX:
                Integer index = (Integer)parameters[0];
                if (index == null) {
                    return null;
                }

                return this.navigation.indicatorButtons.getToggles().get(index);
            default:
                return super.queryAccessibleAttribute(attribute, parameters);
        }
    }

    public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
        return CustomerPaginationSkin.StyleableProperties.STYLEABLES;
    }

    public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
        return getClassCssMetaData();
    }

    static double computeXOffset(double width, double contentWidth, HPos hpos) {
        if (hpos == null) {
            return 0.0;
        } else {
            switch (hpos) {
                case LEFT:
                    return 0.0;
                case CENTER:
                    return (width - contentWidth) / 2.0;
                case RIGHT:
                    return width - contentWidth;
                default:
                    return 0.0;
            }
        }
    }

    static double computeYOffset(double height, double contentHeight, VPos vpos) {
        if (vpos == null) {
            return 0.0;
        } else {
            switch (vpos) {
                case TOP:
                    return 0.0;
                case CENTER:
                    return (height - contentHeight) / 2.0;
                case BOTTOM:
                    return height - contentHeight;
                default:
                    return 0.0;
            }
        }
    }

    static {
        DEFAULT_ARROW_VISIBLE = Boolean.FALSE;
        DEFAULT_PAGE_INFORMATION_VISIBLE = Boolean.FALSE;
        DEFAULT_PAGE_INFORMATION_ALIGNMENT = Side.BOTTOM;
        DEFAULT_TOOLTIP_VISIBLE = Boolean.FALSE;
    }

    private static class StyleableProperties {
        private static final CssMetaData<Pagination, Boolean> ARROWS_VISIBLE;
        private static final CssMetaData<Pagination, Boolean> PAGE_INFORMATION_VISIBLE;
        private static final CssMetaData<Pagination, Side> PAGE_INFORMATION_ALIGNMENT;
        private static final CssMetaData<Pagination, Boolean> TOOLTIP_VISIBLE;
        private static final CssMetaData<Pagination, Number> ARROW_BUTTON_GAP;
        private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;

        private StyleableProperties() {
        }

        static {
            ARROWS_VISIBLE = new CssMetaData<Pagination, Boolean>("-fx-arrows-visible", BooleanConverter.getInstance(), CustomerPaginationSkin.DEFAULT_ARROW_VISIBLE) {
                public boolean isSettable(Pagination n) {
                    CustomerPaginationSkin skin = (CustomerPaginationSkin)n.getSkin();
                    return skin.arrowsVisible == null || !skin.arrowsVisible.isBound();
                }

                public StyleableProperty<Boolean> getStyleableProperty(Pagination n) {
                    CustomerPaginationSkin skin = (CustomerPaginationSkin)n.getSkin();
                    return (StyleableProperty)skin.arrowsVisibleProperty();
                }
            };
            PAGE_INFORMATION_VISIBLE = new CssMetaData<Pagination, Boolean>("-fx-page-information-visible", BooleanConverter.getInstance(), CustomerPaginationSkin.DEFAULT_PAGE_INFORMATION_VISIBLE) {
                public boolean isSettable(Pagination n) {
                    CustomerPaginationSkin skin = (CustomerPaginationSkin)n.getSkin();
                    return skin.pageInformationVisible == null || !skin.pageInformationVisible.isBound();
                }

                public StyleableProperty<Boolean> getStyleableProperty(Pagination n) {
                    CustomerPaginationSkin skin = (CustomerPaginationSkin)n.getSkin();
                    return (StyleableProperty)skin.pageInformationVisibleProperty();
                }
            };
            PAGE_INFORMATION_ALIGNMENT = new CssMetaData<Pagination, Side>("-fx-page-information-alignment", new EnumConverter(Side.class), CustomerPaginationSkin.DEFAULT_PAGE_INFORMATION_ALIGNMENT) {
                public boolean isSettable(Pagination n) {
                    CustomerPaginationSkin skin = (CustomerPaginationSkin)n.getSkin();
                    return skin.pageInformationAlignment == null || !skin.pageInformationAlignment.isBound();
                }

                public StyleableProperty<Side> getStyleableProperty(Pagination n) {
                    CustomerPaginationSkin skin = (CustomerPaginationSkin)n.getSkin();
                    return (StyleableProperty)skin.pageInformationAlignmentProperty();
                }
            };
            TOOLTIP_VISIBLE = new CssMetaData<Pagination, Boolean>("-fx-tooltip-visible", BooleanConverter.getInstance(), CustomerPaginationSkin.DEFAULT_TOOLTIP_VISIBLE) {
                public boolean isSettable(Pagination n) {
                    CustomerPaginationSkin skin = (CustomerPaginationSkin)n.getSkin();
                    return skin.tooltipVisible == null || !skin.tooltipVisible.isBound();
                }

                public StyleableProperty<Boolean> getStyleableProperty(Pagination n) {
                    CustomerPaginationSkin skin = (CustomerPaginationSkin)n.getSkin();
                    return (StyleableProperty)skin.tooltipVisibleProperty();
                }
            };
            ARROW_BUTTON_GAP = new CssMetaData<Pagination, Number>("-fx-arrow-button-gap", SizeConverter.getInstance(), 4) {
                public boolean isSettable(Pagination n) {
                    CustomerPaginationSkin skin = (CustomerPaginationSkin)n.getSkin();
                    return skin.arrowButtonGap == null || !skin.arrowButtonGap.isBound();
                }

                public StyleableProperty<Number> getStyleableProperty(Pagination n) {
                    CustomerPaginationSkin skin = (CustomerPaginationSkin)n.getSkin();
                    return (StyleableProperty)skin.arrowButtonGapProperty();
                }
            };
            List<CssMetaData<? extends Styleable, ?>> styleables = new ArrayList(SkinBase.getClassCssMetaData());
            styleables.add(ARROWS_VISIBLE);
            styleables.add(PAGE_INFORMATION_VISIBLE);
            styleables.add(PAGE_INFORMATION_ALIGNMENT);
            styleables.add(TOOLTIP_VISIBLE);
            styleables.add(ARROW_BUTTON_GAP);
            STYLEABLES = Collections.unmodifiableList(styleables);
        }
    }

    class IndicatorButton extends ToggleButton {
        private final ListChangeListener<String> updateSkinIndicatorType = (c) -> {
            this.setIndicatorType();
        };
        private final ChangeListener<Boolean> updateTooltipVisibility = (ob, oldValue, newValue) -> {
            this.setTooltipVisible(newValue);
        };
        private int pageNumber;

        public IndicatorButton(int pageNumber) {
            this.pageNumber = pageNumber;
            this.setFocusTraversable(false);
            this.setIndicatorType();
            this.setTooltipVisible(CustomerPaginationSkin.this.isTooltipVisible());
            ((Pagination)CustomerPaginationSkin.this.getSkinnable()).getStyleClass().addListener(this.updateSkinIndicatorType);
            this.setOnAction(new EventHandler<ActionEvent>() {
                public void handle(ActionEvent arg0) {
                    int selected = CustomerPaginationSkin.this.getCurrentPageIndex();
                    if (selected != IndicatorButton.this.pageNumber) {
                        CustomerPaginationSkin.this.pagination.setCurrentPageIndex(IndicatorButton.this.pageNumber);
                        IndicatorButton.this.requestLayout();
                    }

                }
            });
            CustomerPaginationSkin.this.tooltipVisibleProperty().addListener(this.updateTooltipVisibility);
            this.prefHeightProperty().bind(this.minHeightProperty());
            this.setAccessibleRole(AccessibleRole.PAGE_ITEM);
        }

        private void setIndicatorType() {
            if (((Pagination)CustomerPaginationSkin.this.getSkinnable()).getStyleClass().contains("bullet")) {
                this.getStyleClass().remove("number-button");
                this.getStyleClass().add("bullet-button");
                this.setText((String)null);
                this.prefWidthProperty().bind(this.minWidthProperty());
            } else {
                this.getStyleClass().remove("bullet-button");
                this.getStyleClass().add("number-button");
                this.setText(Integer.toString(this.pageNumber + 1));
                this.prefWidthProperty().unbind();
            }

        }

        private void setTooltipVisible(boolean b) {
            if (b) {
                this.setTooltip(new Tooltip(Integer.toString(this.pageNumber + 1)));
            } else {
                this.setTooltip((Tooltip)null);
            }

        }

        public int getPageNumber() {
            return this.pageNumber;
        }

        public void fire() {
            if (this.getToggleGroup() == null || !this.isSelected()) {
                super.fire();
            }

        }

        public void release() {
            ((Pagination)CustomerPaginationSkin.this.getSkinnable()).getStyleClass().removeListener(this.updateSkinIndicatorType);
            CustomerPaginationSkin.this.tooltipVisibleProperty().removeListener(this.updateTooltipVisibility);
        }

        public Object queryAccessibleAttribute(AccessibleAttribute attribute, Object... parameters) {
            switch (attribute) {
                case TEXT:
                    return this.getText();
                case SELECTED:
                    return this.isSelected();
                default:
                    return super.queryAccessibleAttribute(attribute, parameters);
            }
        }

        public void executeAccessibleAction(AccessibleAction action, Object... parameters) {
            switch (action) {
                case REQUEST_FOCUS:
                    ((Pagination)CustomerPaginationSkin.this.getSkinnable()).setCurrentPageIndex(this.pageNumber);
                    break;
                default:
                    super.executeAccessibleAction(action, new Object[0]);
            }

        }
    }

    class NavigationControl extends StackPane {
        private HBox controlBox;
        private Button leftArrowButton;
        private StackPane leftArrow;
        private Button rightArrowButton;
        private StackPane rightArrow;
        private ToggleGroup indicatorButtons;
        private Label pageInformation;
        private double previousWidth = -1.0;
        private double minButtonSize = -1.0;
        private int previousIndicatorCount = 0;

        public NavigationControl() {
            this.getStyleClass().setAll(new String[]{"pagination-control"});
            this.addEventHandler(MouseEvent.MOUSE_PRESSED, (e) -> {
                ((PaginationBehavior)CustomerPaginationSkin.this.getBehavior()).mousePressed(e);
            });
            this.addEventHandler(MouseEvent.MOUSE_RELEASED, (e) -> {
                ((PaginationBehavior)CustomerPaginationSkin.this.getBehavior()).mouseReleased(e);
            });
            this.addEventHandler(MouseEvent.MOUSE_ENTERED, (e) -> {
                ((PaginationBehavior)CustomerPaginationSkin.this.getBehavior()).mouseEntered(e);
            });
            this.addEventHandler(MouseEvent.MOUSE_EXITED, (e) -> {
                ((PaginationBehavior)CustomerPaginationSkin.this.getBehavior()).mouseExited(e);
            });
            this.controlBox = new HBox();
            this.controlBox.getStyleClass().add("control-box");
            this.leftArrowButton = new Button();
            this.leftArrowButton.setAccessibleText(ControlResources.getString("Accessibility.title.Pagination.PreviousButton"));
            this.minButtonSize = this.leftArrowButton.getFont().getSize() * 2.0;
            this.leftArrowButton.fontProperty().addListener((arg0, arg1, newFont) -> {
                this.minButtonSize = newFont.getSize() * 2.0;
                Iterator var4 = this.controlBox.getChildren().iterator();

                while(var4.hasNext()) {
                    Node child = (Node)var4.next();
                    ((Control)child).setMinSize(this.minButtonSize, this.minButtonSize);
                }

                this.requestLayout();
            });
            this.leftArrowButton.setMinSize(this.minButtonSize, this.minButtonSize);
            this.leftArrowButton.prefWidthProperty().bind(this.leftArrowButton.minWidthProperty());
            this.leftArrowButton.prefHeightProperty().bind(this.leftArrowButton.minHeightProperty());
            this.leftArrowButton.getStyleClass().add("left-arrow-button");
            this.leftArrowButton.setFocusTraversable(false);
            HBox.setMargin(this.leftArrowButton, new Insets(0.0, this.snapSize(CustomerPaginationSkin.this.arrowButtonGap.get()), 0.0, 0.0));
            this.leftArrow = new StackPane();
            this.leftArrow.setMaxSize(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
            this.leftArrowButton.setGraphic(this.leftArrow);
            this.leftArrow.getStyleClass().add("left-arrow");
            this.rightArrowButton = new Button();
            this.rightArrowButton.setAccessibleText(ControlResources.getString("Accessibility.title.Pagination.NextButton"));
            this.rightArrowButton.setMinSize(this.minButtonSize, this.minButtonSize);
            this.rightArrowButton.prefWidthProperty().bind(this.rightArrowButton.minWidthProperty());
            this.rightArrowButton.prefHeightProperty().bind(this.rightArrowButton.minHeightProperty());
            this.rightArrowButton.getStyleClass().add("right-arrow-button");
            this.rightArrowButton.setFocusTraversable(false);
            HBox.setMargin(this.rightArrowButton, new Insets(0.0, 0.0, 0.0, this.snapSize(CustomerPaginationSkin.this.arrowButtonGap.get())));
            this.rightArrow = new StackPane();
            this.rightArrow.setMaxSize(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
            this.rightArrowButton.setGraphic(this.rightArrow);
            this.rightArrow.getStyleClass().add("right-arrow");
            this.indicatorButtons = new ToggleGroup();
            this.pageInformation = new Label();
            this.pageInformation.getStyleClass().add("page-information");
            this.getChildren().addAll(new Node[]{this.controlBox});
            this.initializeNavigationHandlers();
            this.initializePageIndicators();
            this.updatePageIndex();
            CustomerPaginationSkin.this.arrowButtonGap.addListener((observable, oldValue, newValue) -> {
                if (newValue.doubleValue() == 0.0) {
                    HBox.setMargin(this.leftArrowButton, (Insets)null);
                    HBox.setMargin(this.rightArrowButton, (Insets)null);
                } else {
                    HBox.setMargin(this.leftArrowButton, new Insets(0.0, this.snapSize(newValue.doubleValue()), 0.0, 0.0));
                    HBox.setMargin(this.rightArrowButton, new Insets(0.0, 0.0, 0.0, this.snapSize(newValue.doubleValue())));
                }

            });
        }

        private void initializeNavigationHandlers() {
            this.leftArrowButton.setOnAction((arg0) -> {
                CustomerPaginationSkin.this.selectPrevious();
                this.requestLayout();
            });
            this.rightArrowButton.setOnAction((arg0) -> {
                CustomerPaginationSkin.this.selectNext();
                this.requestLayout();
            });
            CustomerPaginationSkin.this.pagination.currentPageIndexProperty().addListener((arg0, arg1, arg2) -> {
                CustomerPaginationSkin.this.previousIndex = arg1.intValue();
                CustomerPaginationSkin.this.currentIndex = arg2.intValue();
                this.updatePageIndex();
                if (CustomerPaginationSkin.this.animate) {
                    CustomerPaginationSkin.this.currentAnimatedIndex = CustomerPaginationSkin.this.currentIndex;
                    CustomerPaginationSkin.this.animateSwitchPage();
                } else {
                    CustomerPaginationSkin.this.createPage(CustomerPaginationSkin.this.currentStackPane, CustomerPaginationSkin.this.currentIndex);
                }

            });
        }

        private void initializePageIndicators() {
            this.previousIndicatorCount = 0;
            this.controlBox.getChildren().clear();
            this.clearIndicatorButtons();
            this.controlBox.getChildren().add(this.leftArrowButton);

            for(int i = CustomerPaginationSkin.this.fromIndex; i <= CustomerPaginationSkin.this.toIndex; ++i) {
                IndicatorButton ib = CustomerPaginationSkin.this.new IndicatorButton(i);
                ib.setMinSize(this.minButtonSize, this.minButtonSize);
                ib.setToggleGroup(this.indicatorButtons);
                this.controlBox.getChildren().add(ib);
            }

            this.controlBox.getChildren().add(this.rightArrowButton);
        }

        private void clearIndicatorButtons() {
            Iterator var1 = this.indicatorButtons.getToggles().iterator();

            while(var1.hasNext()) {
                Toggle toggle = (Toggle)var1.next();
                if (toggle instanceof IndicatorButton) {
                    IndicatorButton indicatorButton = (IndicatorButton)toggle;
                    indicatorButton.release();
                }
            }

            this.indicatorButtons.getToggles().clear();
        }

        private void updatePageIndicators() {
            for(int i = 0; i < this.indicatorButtons.getToggles().size(); ++i) {
                IndicatorButton ib = (IndicatorButton)this.indicatorButtons.getToggles().get(i);
                if (ib.getPageNumber() == CustomerPaginationSkin.this.currentIndex) {
                    ib.setSelected(true);
                    this.updatePageInformation();
                    break;
                }
            }

            ((Pagination)CustomerPaginationSkin.this.getSkinnable()).notifyAccessibleAttributeChanged(AccessibleAttribute.FOCUS_ITEM);
        }

        private void updatePageIndex() {
            if (CustomerPaginationSkin.this.pageCount == CustomerPaginationSkin.this.maxPageIndicatorCount && this.changePageSet()) {
                this.initializePageIndicators();
            }

            this.updatePageIndicators();
            this.requestLayout();
        }

        private void updatePageInformation() {
            String currentPageNumber = Integer.toString(CustomerPaginationSkin.this.currentIndex + 1);
            String lastPageNumber = CustomerPaginationSkin.this.getPageCount() == Integer.MAX_VALUE ? "..." : Integer.toString(CustomerPaginationSkin.this.getPageCount());
            this.pageInformation.setText(currentPageNumber + "/" + lastPageNumber);
        }

        private void layoutPageIndicators() {
            double left = this.snappedLeftInset();
            double right = this.snappedRightInset();
            double width = this.snapSize(this.getWidth()) - (left + right);
            double controlBoxleft = this.controlBox.snappedLeftInset();
            double controlBoxRight = this.controlBox.snappedRightInset();
            double leftArrowWidth = this.snapSize(Utils.boundedSize(this.leftArrowButton.prefWidth(-1.0), this.leftArrowButton.minWidth(-1.0), this.leftArrowButton.maxWidth(-1.0)));
            double rightArrowWidth = this.snapSize(Utils.boundedSize(this.rightArrowButton.prefWidth(-1.0), this.rightArrowButton.minWidth(-1.0), this.rightArrowButton.maxWidth(-1.0)));
            double spacing = this.snapSize(this.controlBox.getSpacing());
            double w = width - (controlBoxleft + leftArrowWidth + 2.0 * CustomerPaginationSkin.this.arrowButtonGap.get() + spacing + rightArrowWidth + controlBoxRight);
            if (CustomerPaginationSkin.this.isPageInformationVisible() && (Side.LEFT.equals(CustomerPaginationSkin.this.getPageInformationAlignment()) || Side.RIGHT.equals(CustomerPaginationSkin.this.getPageInformationAlignment()))) {
                w -= this.snapSize(this.pageInformation.prefWidth(-1.0));
            }

            double x = 0.0;
            int indicatorCount = 0;

            int lastIndicatorButtonIndex;
            for(lastIndicatorButtonIndex = 0; lastIndicatorButtonIndex < CustomerPaginationSkin.this.getMaxPageIndicatorCount(); ++lastIndicatorButtonIndex) {
                int index = lastIndicatorButtonIndex < this.indicatorButtons.getToggles().size() ? lastIndicatorButtonIndex : this.indicatorButtons.getToggles().size() - 1;
                double iw = this.minButtonSize;
                if (index != -1) {
                    IndicatorButton ib = (IndicatorButton)this.indicatorButtons.getToggles().get(index);
                    iw = this.snapSize(Utils.boundedSize(ib.prefWidth(-1.0), ib.minWidth(-1.0), ib.maxWidth(-1.0)));
                }

                x += iw + spacing;
                if (x > w) {
                    break;
                }

                ++indicatorCount;
            }

            if (indicatorCount == 0) {
                indicatorCount = 1;
            }

            if (indicatorCount != this.previousIndicatorCount) {
                if (indicatorCount < CustomerPaginationSkin.this.getMaxPageIndicatorCount()) {
                    CustomerPaginationSkin.this.maxPageIndicatorCount = indicatorCount;
                } else {
                    CustomerPaginationSkin.this.maxPageIndicatorCount = CustomerPaginationSkin.this.getMaxPageIndicatorCount();
                }

                if (CustomerPaginationSkin.this.pageCount > CustomerPaginationSkin.this.maxPageIndicatorCount) {
                    CustomerPaginationSkin.this.pageCount = CustomerPaginationSkin.this.maxPageIndicatorCount;
                    lastIndicatorButtonIndex = CustomerPaginationSkin.this.maxPageIndicatorCount - 1;
                } else if (indicatorCount > CustomerPaginationSkin.this.getPageCount()) {
                    CustomerPaginationSkin.this.pageCount = CustomerPaginationSkin.this.getPageCount();
                    lastIndicatorButtonIndex = CustomerPaginationSkin.this.getPageCount() - 1;
                } else {
                    CustomerPaginationSkin.this.pageCount = indicatorCount;
                    lastIndicatorButtonIndex = indicatorCount - 1;
                }

                if (CustomerPaginationSkin.this.currentIndex >= CustomerPaginationSkin.this.toIndex) {
                    CustomerPaginationSkin.this.toIndex = CustomerPaginationSkin.this.currentIndex;
                    CustomerPaginationSkin.this.fromIndex = CustomerPaginationSkin.this.toIndex - lastIndicatorButtonIndex;
                } else if (CustomerPaginationSkin.this.currentIndex <= CustomerPaginationSkin.this.fromIndex) {
                    CustomerPaginationSkin.this.fromIndex = CustomerPaginationSkin.this.currentIndex;
                    CustomerPaginationSkin.this.toIndex = CustomerPaginationSkin.this.fromIndex + lastIndicatorButtonIndex;
                } else {
                    CustomerPaginationSkin.this.toIndex = CustomerPaginationSkin.this.fromIndex + lastIndicatorButtonIndex;
                }

                if (CustomerPaginationSkin.this.toIndex > CustomerPaginationSkin.this.getPageCount() - 1) {
                    CustomerPaginationSkin.this.toIndex = CustomerPaginationSkin.this.getPageCount() - 1;
                }

                if (CustomerPaginationSkin.this.fromIndex < 0) {
                    CustomerPaginationSkin.this.fromIndex = 0;
                    CustomerPaginationSkin.this.toIndex = CustomerPaginationSkin.this.fromIndex + lastIndicatorButtonIndex;
                }

                this.initializePageIndicators();
                this.updatePageIndicators();
                this.previousIndicatorCount = indicatorCount;
            }

        }

        private boolean changePageSet() {
            int index = this.indexToIndicatorButtonsIndex(CustomerPaginationSkin.this.currentIndex);
            int lastIndicatorButtonIndex = CustomerPaginationSkin.this.maxPageIndicatorCount - 1;
            if (CustomerPaginationSkin.this.previousIndex < CustomerPaginationSkin.this.currentIndex && index == 0 && lastIndicatorButtonIndex != 0 && index % lastIndicatorButtonIndex == 0) {
                CustomerPaginationSkin.this.fromIndex = CustomerPaginationSkin.this.currentIndex;
                CustomerPaginationSkin.this.toIndex = CustomerPaginationSkin.this.fromIndex + lastIndicatorButtonIndex;
            } else if (CustomerPaginationSkin.this.currentIndex < CustomerPaginationSkin.this.previousIndex && index == lastIndicatorButtonIndex && lastIndicatorButtonIndex != 0 && index % lastIndicatorButtonIndex == 0) {
                CustomerPaginationSkin.this.toIndex = CustomerPaginationSkin.this.currentIndex;
                CustomerPaginationSkin.this.fromIndex = CustomerPaginationSkin.this.toIndex - lastIndicatorButtonIndex;
            } else {
                if (CustomerPaginationSkin.this.currentIndex >= CustomerPaginationSkin.this.fromIndex && CustomerPaginationSkin.this.currentIndex <= CustomerPaginationSkin.this.toIndex) {
                    return false;
                }

                CustomerPaginationSkin.this.fromIndex = CustomerPaginationSkin.this.currentIndex - index;
                CustomerPaginationSkin.this.toIndex = CustomerPaginationSkin.this.fromIndex + lastIndicatorButtonIndex;
            }

            if (CustomerPaginationSkin.this.toIndex > CustomerPaginationSkin.this.getPageCount() - 1) {
                if (CustomerPaginationSkin.this.fromIndex > CustomerPaginationSkin.this.getPageCount() - 1) {
                    return false;
                }

                CustomerPaginationSkin.this.toIndex = CustomerPaginationSkin.this.getPageCount() - 1;
            }

            if (CustomerPaginationSkin.this.fromIndex < 0) {
                CustomerPaginationSkin.this.fromIndex = 0;
                CustomerPaginationSkin.this.toIndex = CustomerPaginationSkin.this.fromIndex + lastIndicatorButtonIndex;
            }

            return true;
        }

        private int indexToIndicatorButtonsIndex(int index) {
            if (index >= CustomerPaginationSkin.this.fromIndex && index <= CustomerPaginationSkin.this.toIndex) {
                return index - CustomerPaginationSkin.this.fromIndex;
            } else {
                int i = 0;
                int from = CustomerPaginationSkin.this.fromIndex;
                int to = CustomerPaginationSkin.this.toIndex;
                if (CustomerPaginationSkin.this.currentIndex > CustomerPaginationSkin.this.previousIndex) {
                    while(from < CustomerPaginationSkin.this.getPageCount() && to < CustomerPaginationSkin.this.getPageCount()) {
                        from += i;
                        to += i;
                        if (index >= from && index <= to) {
                            if (index == from) {
                                return 0;
                            }

                            if (index == to) {
                                return CustomerPaginationSkin.this.maxPageIndicatorCount - 1;
                            }

                            return index - from;
                        }

                        i += CustomerPaginationSkin.this.maxPageIndicatorCount;
                    }
                } else {
                    while(from > 0 && to > 0) {
                        from -= i;
                        to -= i;
                        if (index >= from && index <= to) {
                            if (index == from) {
                                return 0;
                            }

                            if (index == to) {
                                return CustomerPaginationSkin.this.maxPageIndicatorCount - 1;
                            }

                            return index - from;
                        }

                        i += CustomerPaginationSkin.this.maxPageIndicatorCount;
                    }
                }

                return CustomerPaginationSkin.this.maxPageIndicatorCount - 1;
            }
        }

        private Pos sideToPos(Side s) {
            if (Side.TOP.equals(s)) {
                return Pos.TOP_CENTER;
            } else if (Side.RIGHT.equals(s)) {
                return Pos.CENTER_RIGHT;
            } else {
                return Side.BOTTOM.equals(s) ? Pos.BOTTOM_CENTER : Pos.CENTER_LEFT;
            }
        }

        protected double computeMinWidth(double height) {
            double left = this.snappedLeftInset();
            double right = this.snappedRightInset();
            double leftArrowWidth = this.snapSize(Utils.boundedSize(this.leftArrowButton.prefWidth(-1.0), this.leftArrowButton.minWidth(-1.0), this.leftArrowButton.maxWidth(-1.0)));
            double rightArrowWidth = this.snapSize(Utils.boundedSize(this.rightArrowButton.prefWidth(-1.0), this.rightArrowButton.minWidth(-1.0), this.rightArrowButton.maxWidth(-1.0)));
            double spacing = this.snapSize(this.controlBox.getSpacing());
            double pageInformationWidth = 0.0;
            Side side = CustomerPaginationSkin.this.getPageInformationAlignment();
            if (Side.LEFT.equals(side) || Side.RIGHT.equals(side)) {
                pageInformationWidth = this.snapSize(this.pageInformation.prefWidth(-1.0));
            }

            double arrowGap = CustomerPaginationSkin.this.arrowButtonGap.get();
            return left + leftArrowWidth + 2.0 * arrowGap + this.minButtonSize + 2.0 * spacing + rightArrowWidth + right + pageInformationWidth;
        }

        protected double computeMinHeight(double width) {
            return this.computePrefHeight(width);
        }

        protected double computePrefWidth(double height) {
            double left = this.snappedLeftInset();
            double right = this.snappedRightInset();
            double controlBoxWidth = this.snapSize(this.controlBox.prefWidth(height));
            double pageInformationWidth = 0.0;
            Side side = CustomerPaginationSkin.this.getPageInformationAlignment();
            if (Side.LEFT.equals(side) || Side.RIGHT.equals(side)) {
                pageInformationWidth = this.snapSize(this.pageInformation.prefWidth(-1.0));
            }

            return left + controlBoxWidth + right + pageInformationWidth;
        }

        protected double computePrefHeight(double width) {
            double top = this.snappedTopInset();
            double bottom = this.snappedBottomInset();
            double boxHeight = this.snapSize(this.controlBox.prefHeight(width));
            double pageInformationHeight = 0.0;
            Side side = CustomerPaginationSkin.this.getPageInformationAlignment();
            if (Side.TOP.equals(side) || Side.BOTTOM.equals(side)) {
                pageInformationHeight = this.snapSize(this.pageInformation.prefHeight(-1.0));
            }

            return top + boxHeight + pageInformationHeight + bottom;
        }

        protected void layoutChildren() {
            double top = this.snappedTopInset();
            double bottom = this.snappedBottomInset();
            double left = this.snappedLeftInset();
            double right = this.snappedRightInset();
            double width = this.snapSize(this.getWidth()) - (left + right);
            double height = this.snapSize(this.getHeight()) - (top + bottom);
            double controlBoxWidth = this.snapSize(this.controlBox.prefWidth(-1.0));
            double controlBoxHeight = this.snapSize(this.controlBox.prefHeight(-1.0));
            double pageInformationWidth = this.snapSize(this.pageInformation.prefWidth(-1.0));
            double pageInformationHeight = this.snapSize(this.pageInformation.prefHeight(-1.0));
            this.leftArrowButton.setDisable(false);
            this.rightArrowButton.setDisable(false);
            if (CustomerPaginationSkin.this.currentIndex == 0) {
                this.leftArrowButton.setDisable(true);
            }

            if (CustomerPaginationSkin.this.currentIndex == CustomerPaginationSkin.this.getPageCount() - 1) {
                this.rightArrowButton.setDisable(true);
            }

            this.applyCss();
            this.leftArrowButton.setVisible(CustomerPaginationSkin.this.isArrowsVisible());
            this.rightArrowButton.setVisible(CustomerPaginationSkin.this.isArrowsVisible());
            this.pageInformation.setVisible(CustomerPaginationSkin.this.isPageInformationVisible());
            this.layoutPageIndicators();
            this.previousWidth = this.getWidth();
            HPos controlBoxHPos = this.controlBox.getAlignment().getHpos();
            VPos controlBoxVPos = this.controlBox.getAlignment().getVpos();
            double controlBoxX = left + CustomerPaginationSkin.computeXOffset(width, controlBoxWidth, controlBoxHPos);
            double controlBoxY = top + CustomerPaginationSkin.computeYOffset(height, controlBoxHeight, controlBoxVPos);
            if (CustomerPaginationSkin.this.isPageInformationVisible()) {
                Pos p = this.sideToPos(CustomerPaginationSkin.this.getPageInformationAlignment());
                HPos pageInformationHPos = p.getHpos();
                VPos pageInformationVPos = p.getVpos();
                double pageInformationX = left + CustomerPaginationSkin.computeXOffset(width, pageInformationWidth, pageInformationHPos);
                double pageInformationY = top + CustomerPaginationSkin.computeYOffset(height, pageInformationHeight, pageInformationVPos);
                if (Side.TOP.equals(CustomerPaginationSkin.this.getPageInformationAlignment())) {
                    pageInformationY = top;
                    controlBoxY = top + pageInformationHeight;
                } else if (Side.RIGHT.equals(CustomerPaginationSkin.this.getPageInformationAlignment())) {
                    pageInformationX = width - right - pageInformationWidth;
                } else if (Side.BOTTOM.equals(CustomerPaginationSkin.this.getPageInformationAlignment())) {
                    controlBoxY = top;
                    pageInformationY = top + controlBoxHeight;
                } else if (Side.LEFT.equals(CustomerPaginationSkin.this.getPageInformationAlignment())) {
                    pageInformationX = left;
                }

                this.layoutInArea(this.pageInformation, pageInformationX, pageInformationY, pageInformationWidth, pageInformationHeight, 0.0, pageInformationHPos, pageInformationVPos);
            }

            this.layoutInArea(this.controlBox, controlBoxX, controlBoxY, controlBoxWidth, controlBoxHeight, 0.0, controlBoxHPos, controlBoxVPos);
        }
    }
}
